package com.guguskins.back.common.handler;

import com.guguskins.back.common.exception.GlobaStatusException;
import com.guguskins.back.common.exception.GlobalException;
import com.guguskins.back.common.exception.GlobalHttpStatusException;
import com.guguskins.back.common.exception.GlobalMsgException;
import com.guguskins.back.entity.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

import java.util.List;

/**
 * @date 2021/5/10 10:01
 */
@Slf4j
@RestControllerAdvice
public class GlobalDefultExceptionHandler {

    /**
     * 直接返回“系统异常”
     */
    @ExceptionHandler(GlobalException.class)
    public ResultVo globalExceptionHandler(GlobalException globalException) {
        return ResultVo.fail("系统异常");
    }

    /**
     * @description:处理由断言，IllegalArgumentException抛出得异常信息
     * @return java.lang.String
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    public ResultVo handleArgError(IllegalArgumentException e){
        return ResultVo.success(e.getMessage());
    }

    /**
     * 返回异常信息
     */
    @ExceptionHandler(GlobalMsgException.class)
    public ResultVo globalMsgExceptionHandler(GlobalMsgException globalMsgException) {
        return ResultVo.fail(globalMsgException.getMessage());
    }

    @Value("${spring.servlet.multipart.max-file-size}")
    private String maxFileSize;
    @Value("${spring.servlet.multipart.max-request-size}")
    private String maxRequestSize;

    @ExceptionHandler(MultipartException.class)
    public ResultVo multipartExceptionHandler(MultipartException ex) {

        String msg = "文件大小超过限制";

        Throwable cause = ex.getCause().getCause();
        if (cause instanceof FileSizeLimitExceededException) {
            msg = "单个上传文件大小不能超过" + maxFileSize;
        } else if (cause instanceof SizeLimitExceededException) {
            msg = "上传文件总大小不能超过" + maxRequestSize;
        }

        return ResultVo.fail(msg);

    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVo methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        String message = "";
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            System.err.println(errors);
            errors.forEach(p -> {
                FieldError fieldError = (FieldError) p;
                log.error("Data check failure : object{" + fieldError.getObjectName() + "},field{" + fieldError.getField() +
                        "},errorMessage{" + fieldError.getDefaultMessage() + "}");

            });
            if (errors.size() > 0) {
                FieldError fieldError = (FieldError) errors.get(0);
                message = fieldError.getDefaultMessage();
            }
        }
        System.err.println(message);
        return ResultVo.fail(message);
    }

    @ExceptionHandler(GlobaStatusException.class)
    public ResultVo globalMsgExceptionHandler(GlobaStatusException globaStatusException) {
        return ResultVo.fail(globaStatusException.getResultStatusEnum().getStatus(), globaStatusException.getResultStatusEnum().getMsg());
    }

    @ExceptionHandler(GlobalHttpStatusException.class)
    public ResponseEntity<ResultVo> globalHttpStatusExceptionHandler(GlobalHttpStatusException e) {
        return ResponseEntity.status(e.getHttpResponseEnum().getCode())
                .body(ResultVo.fail(e.getHttpResponseEnum().getMsg()));
    }
}
